import { isArray, isObject } from "../is/index";

interface createTreeConfigMode {
    parentKey?: string; //父级的id的key
    ownKey?: string; //自身的id的key
    childrenKey?: string; //存放子节点的key，默认children
    sortFn?: (a?: any, b?: any) => number; // 排序函数,默认树节点排在前面，叶节点在后面
}

/**
 * 根据返回的数组创建树接口
 * @param  arr
 * @param  config，例：{ parentKey: "pid", ownKey: "id" } ，parentKey为父节点唯一标识的字段名，例如pid，ownKey为自己的唯一表示，如id
 * @return 返回创建好的树
 */

export const createTree = (arr: any[], config?: createTreeConfigMode) => {
    if (!isArray(arr)) {
        return arr;
    }
    let _config: createTreeConfigMode = {
        parentKey: "pid",
        ownKey: "id",
        childrenKey: "children",
        sortFn: (a, b) => {
            if (a.isLeaf && !b.isLeaf) {
                return 1;
            }
            if (!a.isLeaf && b.isLeaf) {
                return -1;
            }
            return 0;
        },
        ...(isObject(config) ? config : {}),
    };
    const id: string = _config.ownKey as string;
    const pid: string = _config.parentKey as string;
    const children: string = _config.childrenKey as string;
    let index: number = 0;
    let tmp = arr.map(m => {
            return {
                ...m,
                [children]: [],
                isLeaf: true,
            };
        }),
        f = (data: any, flag?: boolean) => {
            if (isArray(data)) {
                for (let k = 0; k < data.length; k++) {
                    if (tmp[index][pid] == data[k][id]) {
                        if (
                            !data[k][children]
                                .map((m: any) => {
                                    return m[id];
                                })
                                .includes(tmp[index][id])
                        ) {
                            data?.[k]?.[children]?.push(tmp.splice(index, 1)[0]);
                            data[k] && (data[k].isLeaf = false);
                            index--;
                        }
                        break;
                    } else if (tmp[index][id] == data[k][pid]) {
                        if (
                            !tmp[index][children]
                                .map((m: any) => {
                                    return m[id];
                                })
                                .includes(data[k][id])
                        ) {
                            tmp?.[index]?.[children]?.push(data.splice(k, 1)[0]);
                            tmp[index] && (tmp[index].isLeaf = false);
                            if (!flag) {
                                index--;
                            }
                        }
                        break;
                    } else {
                        f(data[k][children], true);
                    }
                }
                (data as any[]).sort(_config?.sortFn);
            }
        };

    for (index = 0; index < tmp.length; index++) {
        f(tmp);
    }
    return tmp;
};
